import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

import { UserModule } from './user/user.module';
import { CatsService } from './cats/cats.service';
import { CatsController } from './cats/cats.controller';
import { CatsModule } from './cats/cats.module';
import { logger } from 'src/middleware/logger.middleware';
import helmet from 'helmet';
import cors from 'cors';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
import { HttpExceptionFilter } from './cats/http-exception.filter';
import { ValidationPipe } from './cats/validation.pipe';
import { RolesGuard } from './cats/roles.guard';
import { LoggingInterceptor } from './cats/logging.interceptor';
import { ConfigService } from './cats/config.service';
import { DevelopmentConfigService } from './cats/development.config.service';
import { ProductionConfigService } from './cats/production.config.service';
import connection from './cats/connection';
// import { LoggerMiddleware } from 'src/middleware/logger.middleware';

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

const mockCatsService = {};

@Module({
  imports: [UserModule, CatsModule],
  controllers: [AppController, CatsController],
  providers: [
    AppService,
    CatsService,
    configServiceProvider,
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply()
      .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.PUT },
      )
      .forRoutes(CatsController);
  }
}
